package org.ytor.core.querygen.support;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.ytor.common.util.Strs;
import org.ytor.core.querygen.AbsWhere;
import org.ytor.core.querygen.token.Token;
import org.ytor.core.sqlflow.builder.support.WhereBuilder;

import java.util.List;

/**
 * created by yangtong on 2025/8/11 14:22:10
 * <br/>
 * or查询，例如age_or = 1,2,3，可以变成age=1 or age=2 or age=3<p>
 * 可以和like查询配合使用，比如age_or=*1*,*2*,*3* -> age like '%1%' or age like '%2%' or age like '%3%'
 */
@Component
public class OrWhere extends AbsWhere {

    @Autowired
    private List<AbsWhere> conditions; // 递归分发用（和原来一样）

    @Override
    public Boolean isMatch(Token token) {
        return Strs.isNotEmpty(token.getKey()) && token.getKey().endsWith("_or");
    }

    @Override
    protected WhereBuilder positive(WhereBuilder where, Token token) {
        String realKey = token.getKey().substring(0, token.getKey().length() - 3);
        String[] subValues = token.getValue().split(",");
        return (WhereBuilder) where.or(nested -> {
            for (String sub : subValues) {
                Token t = new Token(realKey, true, sub);
                for (AbsWhere c : conditions) {
                    if (Boolean.TRUE.equals(c.isMatch(t))) {
                        c.apply((WhereBuilder) nested, t);
                        break;
                    }
                }
            }
            return nested;
        });
    }

    @Override
    protected WhereBuilder negate(WhereBuilder where, Token token) {
        // NOT (x1 OR x2 ...) = (NOT x1) AND (NOT x2) ...
        String realKey = token.getKey().substring(0, token.getKey().length() - 3);
        String[] subValues = token.getValue().split(",");
        return (WhereBuilder) where.and(nested -> {
            for (String sub : subValues) {
                Token t = new Token(realKey, false, sub); // 直接置为负向
                for (AbsWhere c : conditions) {
                    if (Boolean.TRUE.equals(c.isMatch(t))) {
                        c.apply((WhereBuilder) nested, t);
                        break;
                    }
                }
            }
            return nested;
        });
    }

    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    }

    @Override
    public WhereBuilder apply(WhereBuilder where, Token token) {
        return positiveOrNegate(where, token);
    }
}
